home *** CD-ROM | disk | FTP | other *** search
/ Magnum One / Magnum One (Mid-American Digital) (Disc Manufacturing).iso / d12 / c_wndw.arc / DBFDICT.C < prev    next >
Text File  |  1990-01-28  |  12KB  |  335 lines

  1. /*    (c) Marietta Systems, Inc 1987
  2. *    All rights reserved */
  3. /*    
  4. *    This program sets up the dictionary for a dBase3+ file
  5. *
  6. *    The maximum number of fields is 20, and memo fields are not supported
  7. */
  8. #include "mtest.h"
  9. int  dbf_cr(char*);
  10. int  dbf_init(int*, struct DBF_DEF*, char*, int);
  11. int  dbf_name(byte*);
  12. void linedisp(struct DBF_DEF*, int);
  13. int  lineacpt(struct DBF_DEF*, int);
  14. void lineshuf(struct DBF_DEF*, int, int);
  15. #define point "\075\020"
  16. #ifdef LATTICE
  17. #define memmove memcpy
  18. #endif
  19. /*
  20. *
  21. *        Function to create dbase3+ file & setup data dictionary 
  22. *
  23. */
  24. int dbf_cr(name)
  25. char *name;{
  26.     struct DBF_DEF format[20];
  27.     int fields = 0, fld = 0, fh = fileopen(name, dbase3, recreate), z, ret;
  28.     byte kk = 0;
  29.     if (fh < 0) return fh;
  30.   /* setup */
  31.     for (z = 0; z < 20; format[z++].dbf_type = 'C')
  32.         format[z].dbf_name[0] = format[z].dbf_len = format[z].dbf_dec = 0;
  33.   /* setup function key map */
  34.     KEYMATCH[0] = 0X430; /* Up & right arrow, Ctrl+Enter */
  35.     KEYMATCH[1] = 0X108; /* Down & left arrow */
  36.     KEYMATCH[2] = KEYMATCH[3] = KEYMATCH[6] = KEYMATCH[7] = 0;
  37.     KEYMATCH[4] = 0X3000; /* F5, F6 */
  38.     disp_err("",1); /* force display of new function keys */
  39.     if (1 > mk_wndw(TOP_LINE + 1, 1, SCRN_LEN - 1, 80,
  40.         "Enter data dictionary details for dBase3+ file")) goodbye(13);
  41.     kk = INSERT; /* must first insert into an empty dictionary */
  42.     linedisp(format, 0);
  43.   /* main accept loop */
  44.     for(;;){
  45.         if (!kk) linedisp(format, fld);
  46.         display(point, fld+1, 5, blink);
  47.         set_crsr(fld+1, 1);
  48.         if (!kk) kk = grabchar();
  49.         display(": ", fld+1, 5, high);
  50.         switch((int)kk){
  51.             case CRS_UP: if (fld) fld--; kk = 0; break;
  52.             case CRS_DN: if (fld < 20 && fld < fields) fld++; 
  53.                 kk = 0; break;
  54.             case CRS_RT: case ENTER: case TAB: 
  55.                 if (fld == fields) {kk = INSERT; break;}
  56.                 if ((ret = lineacpt(format, fld)) < 0) goodbye(11);
  57.                 kk = (ret ? INCHAR : 0); 
  58.                 if (format[fld].dbf_name[0] == 0 && fields != fld)
  59.                     {lineshuf(format, fld, 1); fields--;}
  60.                 break;
  61.             case QUIT: kk = 0; break;
  62.             case INSERT: if (fields >= 20) 
  63.                     {disp_err("No more fields allowed",1); break;}
  64.                 if (fld < fields) lineshuf(format, fld, -1);
  65.                 if ((ret = lineacpt(format, fld)) < 0) goodbye(11);
  66.                 kk = (ret ? INCHAR : 0); 
  67.                 if (format[fld].dbf_name[0] == 0)
  68.                     lineshuf(format, fld, 1); 
  69.                     else {fld++; fields++;}
  70.                 if (!kk && fld >= fields - 1) kk = INSERT;
  71.             break;
  72.             case DELETE:if (fields && fld < fields) 
  73.                     {lineshuf(format, fld, 1); fields--;}
  74.                 kk = 0; break;
  75.             case HELP: if (mk_wndw(3,48,13,80,"Dictionary help") > 1){
  76.                     display("To change a line, move the    ",1,1,high);
  77.                     display("  cursor with the up and down ",2,1,high);
  78.                     display("  keys, then make your selec- ",3,1,high);
  79.                     display("  tion with the Enter key.    ",4,1,high);
  80.                     display("To insert a line press F5 key ",5,1,high);
  81.                     display("To delete a line press F6 key ",6,1,high);
  82.                     display("To exit, press the F10 key    ",7,1,high);
  83.                     display("<< Press ESC key to continue>>",9,1,low);
  84.                     while(grabchar() != ESC) 
  85.                         disp_err("Press ESC key", 2);
  86.                     rm_wndw();
  87.                     }
  88.                 kk = 0; break; 
  89.             default: warble(1000); idleloop(ERR_BEEP); warble(0); 
  90.                 kk = 0; break;
  91.             } /* end switch */
  92.         if (INCHAR == QUIT && disp_qry("Have you completed entry")) 
  93.             break;
  94.         } /* end for loop */
  95.     ret =  ((fields && disp_qry("Write the dictionary to file")) ?
  96.         dbf_init(&fh, format, name, fields) : -1);
  97.     fileclos(fh); rm_wndw(); return ret;
  98.     }  /* end function dbf_cr */
  99. /*
  100. *
  101. *        Function to write dictionary to new dbase3+ file
  102. *
  103. */
  104. int dbf_init(fh, format, name, fields)
  105. int *fh, fields;
  106. struct DBF_DEF *format; 
  107. char *name;{
  108.     int z;
  109.     short *sptr;
  110.     long rec_nbr = 0L;
  111.     fileinit(*fh, 0, 32, 0L); /* nil start, 32 byte record file */
  112.     memset(FN[*fh].record, 0, 32);
  113.   /* write the system header 32 byte record */
  114.     FN[*fh].record[0] = SYS_REC;
  115.     sptr = (short *) &FN[*fh].record[8];
  116.     sptr[0] = fields * 32    + 33; /* start of data */
  117.     for (sptr[1] = 1, z = 0 ; z < fields ; z++) 
  118.         {sptr[1] += format[z].dbf_len;} /* data record length */
  119.     if (filewrit(*fh, &rec_nbr) < 0) goto error;
  120.   /* write the field dictionary records */
  121.     for (z = 0 ; z < fields ; z++){
  122.         memset(FN[*fh].record, 0, 32);
  123.         memmove(FN[*fh].record, format[z].dbf_name, 11);
  124.         FN[*fh].record[11] = format[z].dbf_type;
  125.         FN[*fh].record[16] = format[z].dbf_len;
  126.         FN[*fh].record[17] = format[z].dbf_dec;
  127.         if (filewrit(*fh, &rec_nbr) < 0) goto error;
  128.         }
  129.   /* write the dBase3+ header terminator */
  130.       FN[*fh].rec_len = 1; /* hairy but necessary technique here */
  131.       FN[*fh].record[0] = 0X0D;        
  132.       if (filewrit(*fh, &rec_nbr) < 0) goto error;
  133.     FN[*fh].rec_len = 32; 
  134.     FN[*fh].prime = 0L; /* set file record count back to zero */
  135.     return 0;
  136.     error: fileclos(*fh); 
  137.     disp_msg("Terminate?? in dbf_init ",(int)rec_nbr + 100); read_kb();
  138.     *fh = fileopen(name, dbase3, recreate);
  139.     return -1;
  140.     } /* end function dbf_init */
  141. /*
  142. *
  143. *        Function to display line of data dictionary
  144. *
  145. */
  146. void linedisp(format, line)
  147. struct DBF_DEF *format;
  148. int line; {
  149.     byte text[12];
  150.     display("Name: ", line + 1, 1, high);
  151.     justify(left, text, format[line].dbf_name, 10, 0);
  152.     display(text, 0, 0, ACC_DISP); 
  153.     display("  Type: ", 0, 0, high);
  154.     switch((int)format[line].dbf_type){
  155.         case 0:
  156.         case 32: 
  157.         case 'C':display("Character", 0, 0, ACC_DISP); break;
  158.         case 'D':display("Date     ", 0, 0, ACC_DISP); break;
  159.         case 'L':display("Logical  ", 0, 0, ACC_DISP); break;
  160.         case 'M':display("Memo     ", 0, 0, ACC_DISP); break;
  161.         case 'N':display("Numeric  ", 0, 0, ACC_DISP); break;
  162.         default: display("?????????", 0, 0, ACC_DISP); break;
  163.         }
  164.     display("  Size: ", 0, 0, high);
  165.     if (format[line].dbf_type == 'N') 
  166.         sprintf(text,"%3u %u",format[line].dbf_len, format[line].dbf_dec);
  167.         else sprintf(text, "%3u  ", format[line].dbf_len); 
  168.     display(text, 0, 0, ACC_DISP); display(" ", line+1, 45, low);
  169.     }  /* end function linedisp */
  170. /*
  171. *
  172. *        Function to validate a dbase3+ field name
  173. *
  174. */
  175. int dbf_name (name)
  176. byte *name;{
  177.     int z, len;
  178.     concat(name, 0); /* strip trailing spaces */
  179.     strupr(name);    /* turn alpha characters into uppercase */
  180.     len = strlen(name);
  181.     if (len > 10 || !len || !isalpha(name[0])) goto error;
  182.     for (z = 1 ; z < len ; z++) 
  183.         if (!isalpha(name[z]) && !isdigit(name[z]) && name[z] != '_')
  184.             goto error;
  185.     return 1;
  186.     error: disp_err("Invalid character in fieldname",3);
  187.     return 0;
  188.     }
  189. /*
  190. *
  191. *        Function to accept a new line in dictionary
  192. *
  193. */
  194. #define CR_MSG0 "                               "
  195. #define CR_MSG1 " Char, Date, Logical, Numeric  "
  196. #define CR_MSG2 " Maximum of 254 bytes in size  "
  197. #define CR_MSG3 " Maximum of 32 bytes in Numeric"
  198. #define CR_MSG4 " Maximum of 8 decimal places   "
  199. #define CR_MSG5 " Only A - Z, 0 - 9, and _      "
  200. int lineacpt(format, fld)
  201. struct DBF_DEF *format;
  202. int fld;{
  203.     int ret, ans, z;
  204.     char text[12];
  205.   /*    */
  206.     name: display(CR_MSG5, fld+1, 48, low);
  207.       set_crsr(fld+1, 7);
  208.     ret = accept(format[fld].dbf_name, left, alt_reverse, 10, 0);
  209.       if (ret && INCHAR != CRS_RT) goto end;
  210.     if (!dbf_name(format[fld].dbf_name)) goto name;
  211.     display(format[fld].dbf_name, fld+1, 7, ACC_DISP);
  212.     for (z = 0 ; z < 20 ; z++) 
  213.         if (z != fld && !strcmp((byte*)format[fld].dbf_name, 
  214.             (byte*)format[z].dbf_name))
  215.             {disp_err("Duplicate name",3); goto name;}
  216.   /*    */
  217.     type: display(CR_MSG1, fld+1, 48, low);
  218.       set_crsr(fld+1, 25);
  219.     text[0] = format[fld].dbf_type; text[1] = 0;
  220.     ret = accept(text, left, alt_reverse, 1, 0);
  221.     if (ret) if (INCHAR == CTL_ENT || INCHAR == CRS_LT) goto name; 
  222.         else if (INCHAR != CRS_RT) goto end;
  223.     format[fld].dbf_type = text[0] = toupper(text[0]);
  224.    /*    */
  225.     switch ((int)text[0]){
  226.         case 'C': display("Character", fld+1, 25, ACC_DISP);
  227.             sprintf(text, "%3u", format[fld].dbf_len);
  228.             c_size: display(CR_MSG2, fld+1, 48, low);
  229.               set_crsr(fld+1, 42);
  230.             ret = accept(text, code, alt_low, 3, 0);
  231.             if (ret) if (INCHAR == CTL_ENT || INCHAR == CRS_LT) 
  232.             goto type; 
  233.                 else break;
  234.             if ((ans = atoi(text)) > 254 || !ans) 
  235.                 {disp_err("size must be 1 thru 254", 1); goto c_size;}
  236.             format[fld].dbf_len = ans;
  237.             break;
  238.         case 'D': break;
  239.         case 'L': break;
  240.         case 'N': display("Numeric  ", fld+1, 25, ACC_DISP);
  241.             n1_size: sprintf(text, "%3u", format[fld].dbf_len);
  242.             display(CR_MSG3, fld+1, 48, low);
  243.               set_crsr(fld+1, 42);
  244.             ret = accept(text, code, alt_low, 3, 0);
  245.             if (ret) if (INCHAR == CTL_ENT || INCHAR == CRS_LT) 
  246.             goto type; 
  247.                 else if (INCHAR != CRS_RT) break;
  248.             if ((ans = atoi(text)) > 32 || !ans) 
  249.                 {disp_err("size must be 1 thru 32", 1); goto n1_size;}
  250.             format[fld].dbf_len = ans;
  251.             n2_size: sprintf(text, "%1u", format[fld].dbf_dec);
  252.             display(CR_MSG4, fld+1, 48, low);
  253.               set_crsr(fld+1, 46);
  254.             ret = accept(text, code, alt_low, 1, 0);
  255.             if (ret) if (INCHAR == CTL_ENT || INCHAR == CRS_LT) 
  256.             goto n1_size; 
  257.                 else break;
  258.             if ((ans = atoi(text)) > 8) 
  259.                 {disp_err("Maximum of 8 decimal places", 1); 
  260.                 goto n2_size;}
  261.             format[fld].dbf_dec = ans;
  262.             break;
  263.          default: disp_err("Invalid type selection", 1); goto type;
  264.          } /* end switch */
  265.   /*  exit validation */
  266.     end: if (!format[fld].dbf_name[0]) return ret; /* empty */
  267.     switch((int)format[fld].dbf_type){
  268.         case 'C': format[fld].dbf_dec = 0;
  269.             if (format[fld].dbf_len == 255) goto c_size;
  270.             break;
  271.         case 'D': format[fld].dbf_len = 8; 
  272.             format[fld].dbf_dec = 0; break;
  273.         case 'L': format[fld].dbf_len = 1;
  274.             format[fld].dbf_dec = 0; break;
  275.         case 'N': if (format[fld].dbf_len > 32) goto n1_size;
  276.             if (format[fld].dbf_dec > 8) goto n2_size;
  277.             if (format[fld].dbf_dec + 2 > format[fld].dbf_len) 
  278.                     goto n1_size;
  279.             break;
  280.         default: goto type;
  281.         } /* end switch */
  282.     display(CR_MSG0, fld+1, 48, low); /* blank out help area */
  283.     if (!format[fld].dbf_len) memset(format[fld].dbf_name, 0, 11);
  284.     linedisp(format, fld);
  285.     return ret;
  286.     }    /* end function lineacpt */
  287. /*
  288. *
  289. *        Function to shuffle up and down the dictionary display
  290. *
  291. */
  292. void lineshuf(format, fld, up)
  293. struct DBF_DEF *format;
  294. int fld, up;{
  295.     int to, from, base;
  296.     up = (up < 0 ? -1 : 1);
  297.     scroll(up, fld); /* scroll window up or down */
  298.     to = (up > 0 ? fld : 19);
  299.     from = (up > 0 ? fld + 1 : 18);
  300.     base = (up > 0 ? 19 : fld);
  301.     for (; base != to ; to += up, from += up){
  302.         memmove(format[to].dbf_name, format[from].dbf_name, 11);
  303.         format[to].dbf_type = format[from].dbf_type;
  304.         format[to].dbf_len = format[from].dbf_len;
  305.         format[to].dbf_dec = format[from].dbf_dec;
  306.         }
  307.     memset(format[to].dbf_name, 0, 11);
  308.     format[to].dbf_type = 'C';
  309.     format[to].dbf_len = 0;
  310.     format[to].dbf_dec = 0;
  311.     if (up < 0) linedisp(format, fld);
  312.     }     /* end function lineshuf */
  313. /*
  314. *
  315. *    Main section
  316. *
  317. */
  318. void main(){
  319. char name[51];
  320. int z, fh;
  321. clr_scrn("dBase3+ dictionary create");
  322. strcpy(name, "dbftest.dbf");
  323. for (;;){
  324.     for (z = 0 ; z < 8 ; KEYMATCH[z++] = 0); disp_err("",1);
  325.     display("Enter file name  ", 20, 2, low);
  326.     if (accept(name, left, alt_reverse, 50, 0)) goodbye(0);
  327.     if ((fh = fileopen(name, dbase3, readonly)) < 0) continue;
  328.     if (fh && FN[fh].fnext != NULL 
  329.         && !disp_qry("Do you wish to overwrite file")) 
  330.         {fileclos(fh); continue;}
  331.         else if (fh) {fileclos(fh); if (fileback(name) < 1) continue;}
  332.     if (!dbf_cr(name)) {name[0] = 0; disp_err("Dictionary created", 1);}
  333.         else disp_err("Error end to dict create", 2);   
  334.     }
  335. }